<template>
  <div>
    <el-upload
      ref="upload"
      :class="['l-upload', disabled ? 'readonly' : '']"
      action=""
      :http-request="upload"
      :on-preview="handlePreview"
      :on-remove="handleRemove"
      :before-remove="beforeRemove"
      :multiple="multiple"
      :limit="limit"
      :accept="aaccept2"
      :on-exceed="handleExceed"
      :on-success="handlesuccess"
      :before-upload="handleBeforeUpload"
      :file-list="fileList"
      :data="param"
      :list-type="listType"
      :disabled="disabled"
    >
      <div v-if="isTip" slot="tip" class="el-upload__tip">{{ tipMsg }}</div>
      <template v-if="!disabled">
        <el-button
          v-if="!isImg"
          size="mini"
          type="primary"
          icon="el-icon-upload"
          >点击上传</el-button
        >
        <i v-else class="el-icon-plus"></i>
      </template>
    </el-upload>

    <l-dialog
      v-if="!isImg"
      title="文件预览"
      :visible.sync="previewVisible"
      width="1000px"
      :height="800"
    >
      <iframe
        v-if="previewUrl != ''"
        :src="previewUrl"
        class="l-iframe"
        ref="iframe"
        frameborder="0"
      ></iframe>
      <template #btns>
        <el-button
          size="mini"
          icon="el-icon-down"
          type="primary"
          @click="
            downFile(
              `${apiUrl}system/annexesfile/${previewFileId}?token=${token}`
            )
          "
          >下载</el-button
        >
      </template>
    </l-dialog>

    <el-dialog
      :append-to-body="true"
      v-if="isImg"
      :visible.sync="previewVisible"
    >
      <img width="100%" :src="previewUrl" alt="" />
    </el-dialog>
  </div>
</template>

<script>
export default {
  name: "l-upload",
  props: {
    value: {},
    disabled: {
      type: Boolean,
      default: false,
    },

    limit: {
      type: Number,
      default: 1,
    },
    maxSize: String,
    sizeType: String,
    accept: String,
    isTip: Boolean,
    listType: String,
    multiple: {
      type: Boolean,
      default: true,
    },
    uploadCallback: Function,
  },
  watch: {
    value: {
      handler(val, oldVal) {
        if (this.$validatenull(val)) {
          this.folderId = this.$uuid();
          this.fileList = [];
        } else {
          // 加载列表页
          if (
            (val != oldVal && !this.$validatenull(oldVal)) ||
            val != this.folderId
          ) {
            this.handleLoadFileList(val);
          }
        }
      },
      immediate: true,
    },
  },
  data() {
    return {
      folderId: "",
      fileList: [],
      uploadFiles: [],

      previewVisible: false,
      previewFileId: "",
      previewUrl: "",
    };
  },
  created() {
    this.folderId = this.$uuid();
  },
  mounted() {},
  computed: {
    param() {
      return {
        folderId: this.value || this.folderId,
        maxSize: this.maxSize,
        sizeType: this.sizeType,
      };
    },
    tipMsg() {
      return `只能上传不超过${this.maxSize || ""}${this.sizeType || ""}的${
        this.accept || ""
      }文件`;
    },
    isImg() {
      return this.listType == "picture-card";
    },
    aaccept2() {
      if (this.isImg) {
        return "image/*";
      } else {
        return this.accept;
      }
    },
  },
  methods: {
    dispatch(componentName, eventName, params) {
      var parent = this.$parent || this.$root;
      var name = parent.$options.componentName;
      // 从这里可以看出是找到对应的组件对象
      while (parent && (!name || name !== componentName)) {
        parent = parent.$parent;
        if (parent) {
          name = parent.$options.componentName;
        }
      }
      if (parent) {
        parent.$emit.apply(parent, [eventName].concat(params));
      }
    },
    async handleLoadFileList(val) {
      if (this.lr_getFileList) {
        let data = await this.lr_getFileList(val);
        if (val == this.value) {
          this.fileList = data;
        }
        if (data.length == 0) {
          this.$emit("input", "");
        }
      }
    },
    handlesuccess(response) {
      this.uploadFiles.push(response);
      if (!this.value) {
        this.$emit("input", response.folderId);
        setTimeout(() => {
          this.dispatch("ElFormItem", "el.form.blur", ["xxx"]);
        });
      }
    },
    handleRemove(file) {
      if (file.response) {
        this.lr_deleteFile && this.lr_deleteFile(file.response.fileId);
        this.uploadFiles.splice(
          this.uploadFiles.findIndex((t) => t.fileId == file.response.fileId),
          1
        );
      }

      if (file.id) {
        this.lr_deleteFile && this.lr_deleteFile(file.id);
        this.fileList.splice(
          this.fileList.findIndex((t) => t.id == file.id),
          1
        );
      }

      if (this.uploadFiles.length == 0 && this.fileList.length == 0) {
        this.$emit("input", "");
      }
    },

    handlePreview(file) {
      const fileExt = file.name.split(".")[file.name.split(".").length - 1];
      const fileId = file.id || file.response.fileId;
      switch (fileExt) {
        case "xls":
        case "xlsx":
        case "docx":
        case "txt":
        case "csv":
        case "html":
        case "pdf":
          if (this.$validatenull(this.apiUrl)) {
            return;
          }
          this.previewUrl = `${this.apiUrl}system/annexesfile/preview/${fileId}`;
          this.previewFileId = fileId;
          this.previewVisible = true;
          break;
        case "jpg":
        case "gif":
        case "png":
        case "bmp":
        case "jpeg":
        case "svg":
          if (this.isImg) {
            if (file.url) {
              this.previewUrl = file.url;
            } else {
              if (this.$validatenull(this.apiUrl)) {
                return;
              }
              this.previewUrl = `${this.apiUrl}system/annexesfile/preview/${fileId}`;
            }
            this.previewVisible = true;
          } else {
            if (this.$validatenull(this.apiUrl)) {
              return;
            }
            this.previewUrl = `${this.apiUrl}system/annexesfile/preview/${fileId}`;
            this.previewFileId = fileId;
            this.previewVisible = true;
            break;
          }

          break;
        default: // 不支持预览，就直接下载
          this.$message.warning(`当前文件格式不支持预览${fileExt}`);
          if (this.$validatenull(this.apiUrl)) {
            return;
          }
          this.downFile(`${this.apiUrl}system/annexesfile/${fileId}`);
          break;
      }
    },
    handleExceed(files, fileList) {
      this.$message.warning(
        `当前限制选择 ${this.limit} 个文件，本次选择了 ${
          files.length
        } 个文件，共选择了 ${files.length + fileList.length} 个文件`
      );
    },
    beforeRemove(file) {
      if (!this.compareSize(file.size)) {
        return true;
      }
      return this.$confirm(`确定移除 ${file.name}？`);
    },
    downFile(url) {
      this.$downFile(`${url}`);
    },
    handleBeforeUpload(file) {
      if (!this.compareSize(file.size)) {
        this.$message.warning("上传文件超出大小了");
        return false;
      }
    },
    compareSize(fileSize) {
      if (this.maxSize && this.sizeType) {
        let size = fileSize;
        switch (this.sizeType) {
          case "GB":
            size = 1024 * 1024 * 1024 * Number(this.maxSize);
            break;
          case "MB":
            size = 1024 * 1024 * Number(this.maxSize);
            break;
          case "KB":
            size = 1024 * Number(this.maxSize);
            break;
        }
        if (size < fileSize) {
          return false;
        }
      }
      return true;
    },
    upload(option) {
      if (this.lr_chunkedUpload) {
        this.lr_chunkedUpload(option, this.uploadCallback);
      } else {
        const { file } = option;
        option.onSuccess({
          name: file.name,
        });
      }
    },
  },
};
</script>
<style lang="less">
@import "./index.less";
</style>
